import Watcher from "./observe/watcher";
import { patch } from "./vdom/patch";

export function lifecycleMixin(Vue) {
  // 将 vnode 转为真实 dom
  Vue.prototype._update = function (vnode) {
    const vm = this;
    const prevVnode = vm._vnode; // 用来判断是否是第一次渲染，第一次是不存在的

    // 在 patch 中首次渲染需要用 vnode 来替换真实的 dom 元素，之后的更新就使用 diff 算法
    if (!prevVnode) {
      //首次渲染
      vm.$el = patch(vm.$el, vnode);
    } else {
      // 非首次渲染
      vm.$el = patch(prevVnode, vnode); //
    }
    vm._vnode = vnode; // 更新 _vnode
  };
}

export function callHook(vm, hook) {
  const handlers = vm.$options[hook];
  if (handlers) {
    handlers.forEach((handler) => handler.call(vm));
  }
}

export function mountComponent(vm) {
  // 渲染更新页面
  let updateComponent = () => {
    let vnode = vm._render(); // vm._render() 得到虚拟节点 vnode
    // log("vnode=====", vnode);
    vm._update(vnode); // 将虚拟节点转为真实节点
  };

  // 每个组件都有一个渲染 watcher
  new Watcher(
    vm,
    updateComponent,
    () => {}, // 此函数里面放生命周期函数
    true // 此 watcher 是否是渲染watcher
  );
}
